home *** CD-ROM | disk | FTP | other *** search
- /* PopUpMenu 2.0b4
-
- This HyperCard external function presents the user with a pop-up-
- menu from which she would then select an item. If no item is
- selected NULL is returned to your HyperTalk script. Otherwise,
- the ordinal number of the item selected is returned.
-
- PopUpMenu is called with one to four arguments. The first argument
- is the menu. This menu is a series of menu items. Each item is
- separated by either a comma, semi-colon, carriage-return, line-
- feed, or tab. Each item's characters will be added to the menu
- with AppendMenu; Thus, any of the AppendMenu meta-characters can
- be used (except for the hierarchical menu meta-character).
-
- The second argument is the number of an item to be checked. If
- this argument is missing or empty then no item will be checked.
-
- The third and fourth arguments position the pop-up-menu. The
- coordinates must be global to the screen. (I have retained
- global coordinates to maintain compatibility with PopUpMenu
- 1.x.) If either of these arguments is missing or empty then
- the menu position defaults to the current mouse position.
-
- If all arguments are omitted then version and copyright
- information is returned.
-
- Usage example.
-
- on mouseDown
- get PopUpMenu( "Color,Mono,Psychedelic", 3 );
-
- if it is empty then
- answer "Nothing was selected."
- else
- answer item it of "Color,Mono,Psychedelic" && "was selected."
- end if
- end mouseDown
-
- Good luck with your stacks!
-
-
- Andrew Gilmartin
- Computing & Information Services
- Box 1885
- Brown University
- Providence, Rhode Island 02912
-
- andrew@brownvm.brown.edu (internet)
- andrew@brownvm (bitnet)
-
- Neither I nor Brown University place any restrictions on the use of
- the external HyperTalk function PopUpMenu. I only request that you
- credit myself and Brown University; For example,
-
- PopUpMenu by Andrew Gilmartin, Brown University
-
- PopUpMenu has been tested with HyperCard 1.x and HyperCard 2.0. However,
- the developers have no desire or ability to support this product, and
- therefore PopUpMenu is delivered “as is” with no expressed or implied
- guarantees of operability or support.
-
- */
-
-
-
-
-
- #include "MenuMgr.h"
- #include "HyperXCmd.h"
- #include "utilities.h"
-
-
-
-
-
- #define NULL 0L
-
-
- #define FALSE 0
- #define TRUE 1
-
-
- #define loop for(;;)
-
-
-
- #define MENU_ID 1024
- int gMenuID;
-
-
-
- int unusedMenuID( int menuID );
-
- int unusedMenuID( int menuID )
- {
- while ( GetMHandle( menuID++ ) );
-
- return( menuID - 1 );
-
- } /* unusedMenuID */
-
-
-
-
- MenuHandle popupmenu_create_menu( char * menu_items );
-
- MenuHandle popupmenu_create_menu( menu_items )
- char * menu_items;
- {
- MenuHandle the_menu;
- char c;
- struct
- {
- Str255 content;
- char * pointer; /* where the next character should be placed in .content */
- int length;
- } menu_item;
-
-
- gMenuID = unusedMenuID( MENU_ID );
-
- if ( ( the_menu = NewMenu( gMenuID, "\p" ) ) != NULL )
- {
- menu_item.pointer = (char *) &menu_item.content;
- menu_item.length = 0;
-
- loop
- {
- switch ( c = *menu_items++ )
- {
- case ',': /* I figure that these cases should cover most */
- case ';': /* uses of PopUpMenu... */
- case '\n':
- case '\r':
- case '\t':
- if ( menu_item.length > 0 )
- {
- *menu_item.pointer = '\0'; /* C strings end in a null! */
- CtoPstr( (char *) &menu_item.content );
- AppendMenu( the_menu, &menu_item.content );
- }
-
- menu_item.pointer = (char *) &menu_item.content;
- menu_item.length = 0;
- break;
-
- case '\0':
- if ( menu_item.length > 0 )
- {
- *menu_item.pointer = '\0'; /* C strings end in a null! */
- CtoPstr( (char *) &menu_item.content );
- AppendMenu( the_menu, &menu_item.content );
- }
- goto outside_loop;
-
- default:
- if ( menu_item.length < ( sizeof( menu_item.content ) - 1 ) )
- *menu_item.pointer++ = c,
- menu_item.length++;
- }
-
- }
- outside_loop:;
- }
-
- return the_menu;
-
- } /* popupmenu_create_menu */
-
-
-
-
-
- int popupmenu( char * menu_items, int checked_item, Point mouse_location );
-
- int popupmenu( menu_items, checked_item, mouse_location )
- char * menu_items;
- int checked_item;
- Point mouse_location;
- {
- MenuHandle the_menu;
- long the_selected_item = 0;
- int the_checked_item;
-
-
- /* Create Menu */
-
- the_menu = popupmenu_create_menu( menu_items );
- if ( the_menu == NULL )
- return 0;
-
-
- /* Check Menu Item */
-
- if ( checked_item > 0 && checked_item <= CountMItems( the_menu ) )
- {
- CheckItem( the_menu, checked_item, TRUE );
- the_checked_item = checked_item;
- }
- else
- {
- the_checked_item = 1;
- }
-
-
- /* Add the menu to the system */
-
- InsertMenu( the_menu, -1 );
-
-
- /* Get Menu Selection */
-
- the_selected_item = PopUpMenuSelect(
- the_menu,
- mouse_location.v,
- mouse_location.h,
- the_checked_item );
-
-
- /* Remove the menu from the system */
-
- DeleteMenu( gMenuID );
- DisposeMenu( the_menu );
-
-
- /* Return user's selection */
-
- return (int) ( the_selected_item & 0x0000FFFF );
-
- } /* popupmenu */
-
-
-
-
-
- pascal void main( XCmdBlockPtr paramPtr );
-
- pascal void main( paramPtr )
- XCmdBlockPtr paramPtr;
- {
- char * menu_items /* = NULL */;
- int checked_item = -1;
- int selected_item /* = 0 */;
- Point mouse_location;
- int _mouse_location;
-
- XCMDSetupA4();
-
- /* Get Mouse Location
-
- We need to get the mouse location early in the external just in case the
- user mouses ahead. It would be better if the location of the last mouse
- down were available at the toolbox level...
- */
-
- GetMouse( &mouse_location );
- LocalToGlobal( &mouse_location );
-
-
- /* Parse Paramater List */
-
- switch ( paramPtr->paramCount )
- {
- case 4:
- _mouse_location = param_to_integer( paramPtr->params[3] );
- if ( _mouse_location > 0 )
- mouse_location.v = _mouse_location;
-
- case 3:
- _mouse_location = param_to_integer( paramPtr->params[2] );
- if ( _mouse_location > 0 )
- mouse_location.h = _mouse_location;
-
- case 2:
- checked_item = param_to_integer( paramPtr->params[1] );
-
- case 1:
- MoveHHi( paramPtr->params[0] );
- HLock( paramPtr->params[0] );
- menu_items = *(paramPtr->params[0]);
-
- selected_item = popupmenu( menu_items, checked_item, mouse_location );
- if ( selected_item != 0 )
- paramPtr->returnValue = integer_to_param( selected_item );
-
- HUnlock( paramPtr->params[0] );
- break;
-
- case 0:
- paramPtr->returnValue = string_to_param(
- "PopUpMenu 2.0b4 by Andrew Gilmartin, Brown University" );
- break;
-
- default:
- break;
- }
-
- XCMDRestoreA4();
-
- /* Bye, Bye! */
-
- } /* main */